package com.seu.data.structures.hashtable.basics;

import com.seu.data.structures.redblackTree.basics.AVLTree;
import com.seu.data.structures.redblackTree.basics.BST;
import com.seu.data.structures.redblackTree.basics.FileOperation;
import com.seu.data.structures.redblackTree.basics.RBTree;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        System.out.println("Pride and Prejudice");

        ArrayList<String> words = new ArrayList<>();
        if (FileOperation.readFile("F:\\projects\\design_pattern\\src\\main\\resources\\pride-and-prejudice.txt", words)) {
            System.out.println("Total words: " + words.size());

            // Collections.sort(words);

            // Test BST
            long startTime = System.nanoTime();
            BST<String, Integer> bst = new BST<>();
            for (String word : words) {
                if (bst.contains(word)) {
                    bst.set(word, bst.get(word) + 1);
                } else {
                    bst.add(word, 1);
                }
            }

            for (String word : words) {
                bst.contains(word);
            }

            long endTime = System.nanoTime();
            double time = (endTime - startTime) / 1000000000.0;
            System.out.println("BST: " + time + " s");


            // Test AVL
            startTime = System.nanoTime();
            AVLTree<String, Integer> avl = new AVLTree<>();
            for (String word : words) {
                if (avl.contains(word)) {
                    avl.set(word, avl.get(word) + 1);
                } else {
                    avl.add(word, 1);
                }
            }

            for (String word : words) {
                avl.contains(word);
            }

            endTime = System.nanoTime();
            time = (endTime - startTime) / 1000000000.0;
            System.out.println("AVL: " + time + " s");

            // Test RBTree
            startTime = System.nanoTime();
            RBTree<String, Integer> rbt = new RBTree<>();
            for (String word : words) {
                if (rbt.contains(word)) {
                    rbt.set(word, rbt.get(word) + 1);
                } else {
                    rbt.add(word, 1);
                }
            }

            for (String word : words) {
                rbt.contains(word);
            }

            endTime = System.nanoTime();
            time = (endTime - startTime) / 1000000000.0;
            System.out.println("RBTree: " + time + " s");

            // Test HashTable
            startTime = System.nanoTime();
            int M = 131071;
            HashTable<String, Integer> ht = new HashTable<String, Integer>(M);
            for (String word : words) {
                if (ht.contains(word)) {
                    ht.set(word, ht.get(word) + 1);
                } else {
                    ht.add(word, 1);
                }
            }

            for (String word : words) {
                ht.contains(word);
            }

            endTime = System.nanoTime();
            time = (endTime - startTime) / 1000000000.0;
            System.out.println("HashTable: " + time + " s");

            HashTableV2<String, Integer> ht2 = new HashTableV2<String, Integer>();
            for (String word : words) {
                if (ht2.contains(word)) {
                    ht2.set(word, ht2.get(word) + 1);
                } else {
                    ht2.add(word, 1);
                }
            }

            for (String word : words) {
                ht2.contains(word);
            }

            endTime = System.nanoTime();
            time = (endTime - startTime) / 1000000000.0;
            System.out.println("HashTableV2: " + time + " s");

        }

        System.out.println();
    }
}
